##Some Code to test the upload to Googlepages :)
##Teehee

from Tkinter import *

import random


##Transform class
    ##enigma-style rotor-based polyalphabetic substitutive encoding/decoding

class Transform(object):
    """A simple class that returns an output string for a number radio station"""
    rotor_a=1
    rotor_b=1
    rotor_c=1
    ## 'ordered_alphabet' is now obsolete: it is left here merely for reference and to make editing the actual list easier.
    alphabet=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',' ', '0','1','2','3','4','5','6','7','8','9','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    def __init__(self,string_input="NONE"):
        self.string=string_input
        for i in range(0,len(self.string)):
            if self.string[i] not in self.alphabet:
                self.string=self.string.replace(self.string[i],"#") ##Replaces all illigal characters with a "#"
                ## Note I done it this way because I was getting index-out of range errors if I removed the character entirely at this stage.
                
        self.string=self.string.replace('#',"") ## Removes the hash
    def __str__(self):       
        return self.string
        
    def rotor_advance(self):
        """advances the rotor indices by one position"""
        self.rotor_a+=1
        if self.rotor_a>26:
            self.rotor_a=1
            self.rotor_b+=1
        if self.rotor_b>26:
            self.rotor_b=1
            self.rotor_c+=1
        if self.rotor_c>26:
            self.rotor_c=1
            self.rotor_a+=1
            
    def random_letter(self):
        """jumbles the input stirng by character""" ## Its kinda pointless when you think about it...... unless you like anagrams...

        listing=list(self.string)
        random.shuffle(listing)
        return listing
    
    def random_word(self):
        """jumbles the input stirng" by word""" ## This kinda pointless too......
        listing=self.string.split()
        random.shuffle(listing)
        return listing

    def random_shuffle(self):
        """jumbles the input stirng" by word""" ## This kinda pointless too......
        listing=self.string.split()
        random.shuffle(listing)
        listing=list(self.string)
        random.shuffle(listing)
        return listing
        
    def enigma_encode(self,rotor_config="aaa"):
        """Translates a string using an enigma-type polyalphabatic transform."""
        """NOTE this base class only provides the mechanism for parsing a string: endcoding / decoding will be handled by a sub class"""
        while len(rotor_config)<3:
            rotor_config+="0"
        self.rotor_a=self.alphabet.index(rotor_config[0]) ###Figure out how to change the intitial thing xD
        self.rotor_b=self.alphabet.index(rotor_config[1])
        self.rotor_c=self.alphabet.index(rotor_config[2])
        if self.rotor_a>26:
            self.rotor_a=1
            self.rotor_b+=1
        if self.rotor_b>26:
            self.rotor_b=1
            self.rotor_c+=1
        if self.rotor_c>26:
            self.rotor_c=1
            self.rotor_a+=1
        
        output_string=[]
        output_string.insert(0,self.alphabet[self.rotor_a]+self.alphabet[self.rotor_b]+self.alphabet[self.rotor_c])
        # Increase index by one to cycle a reel.
        
        for i in range(0,len(self.string)):
                
            new_letter=self.alphabet.index(self.string[i])+self.rotor_a+self.rotor_b+self.rotor_c
            
            while new_letter>62:
                new_letter-=63
            while new_letter<0:
                new_letter+=63

            
            output_string.insert(len(output_string),self.alphabet[new_letter])
            self.rotor_advance()
        print "Final rotor config:",self.alphabet[self.rotor_a]+self.alphabet[self.rotor_b]+self.alphabet[self.rotor_c]
        delim=""
        return delim.join(output_string)
    
    def enigma_decode(self):
        """Translates a string using an enigma-type polyalphabatic transform."""
        """NOTE this base class only provides the mechanism for parsing a string: endcoding / decoding will be handled by a sub class"""
        
        self.rotor_a=self.alphabet.index(self.string[0])
        self.rotor_b=self.alphabet.index(self.string[1])
        self.rotor_c=self.alphabet.index(self.string[2])
        
        output_string=[]
        
        # Increase index by one to cycle a reel.
        
        for i in range(3,len(self.string)):

            
            new_letter=self.alphabet.index(self.string[i])-self.rotor_a-self.rotor_b-self.rotor_c
            
            while new_letter>62:
                new_letter-=63
            while new_letter<0:
                new_letter+=63

            
            output_string.insert(len(output_string),self.alphabet[new_letter])
            self.rotor_advance()
        
        print "Final rotor config:",self.alphabet[self.rotor_a]+self.alphabet[self.rotor_b]+self.alphabet[self.rotor_c]
        
        delim=""
        return delim.join(output_string)

#-----This point down is the GUI
class Application(Frame):
    scoredict={}
    def __init__(self, master):
        """Initialises the Frame"""
        Frame.__init__(self,master)

        self.grid()
        self.create_widgets()


    def create_widgets(self):
        """Creates the widgets that the initialised frame will use."""
        self.encode_text=Text(self,
                              width=50,
                              height=10,
                              wrap=CHAR)
        self.encode_text.grid(row=2,column=0,sticky=W)
        
        self.decode_text=Text(self,
                              width=50,
                              height=10,
                              wrap=CHAR)
        self.decode_text.grid(row=5,column=0,sticky=W)
        
        self.encode_submit=Button(self,
                           command=self.encoder,
                           text="Encode").grid(row=3,column=0,sticky=W)
        self.decode_submit=Button(self,
                                  command=self.decoder,
                                  text="Decode").grid(row=3,column=0,sticky=E)
        self.rotor_config=Entry(self)
        self.rotor_config.grid(row=0,column=0,sticky=E)
        Label(self,
              text="Enter Initial Rotor Configuration:").grid(row=0,column=0,sticky=W)
        Label(self,
              text="Type message to encode/decode:").grid(row=1,column=0,sticky=W)
        Label(self,
              text="Encoded/decoded message:").grid(row=4,column=0,sticky=W)

    def encoder(self):
        """Updates the text field of the frame"""
        rotorconfig=self.rotor_config.get()
        
        rotorconfig=rotorconfig[:3]
        self.decode_text.delete(0.0,END)
        contents=self.encode_text.get(0.0,END)
        temp_encode=Transform(contents)
        output=temp_encode.enigma_encode(rotorconfig)
        self.decode_text.insert(0.0,output)
        return
    
    def decoder(self):
        """Updates the text field of the frame"""
        self.decode_text.delete(0.0,END)
        contents=self.encode_text.get(0.0,END)
        temp_encode=Transform(contents)
        output=temp_encode.enigma_decode()
        self.decode_text.insert(0.0,output)
        return
       
##-  -  Everything below this is for the radio message itself

class radio_message(object):
    def __init__(self,message="Default Number Radio Test"):
        self.message=message

    def assembler(self,encoding=0):
        #0=no encoding; message appears as-is 1= standard5-digit grouping, no spaces: 2=Transform()-encoding:
        #3=randomised word-order: 4=randomised character-order: 5=randomised character and word order
        """assembled the message into radio-format using vairous methods of encoding"""
        if encoding==0:
            newmessage=self.message
        elif encoding==1:
            print "message will have all spaces removed and then apply 5-digit grouping"
            # remove all spaces
                #insert space in every 5th index
            return
        elif encoding==2:
            messageinstance=Transform(self.message)
            newmessage=messageinstance.enigma_encode()
            
        elif encoding==3:
            messageinstance=Transform(self.message)
            newmessage=messageinstance.random_letter()
            
        elif encoding==4:
            messageinstance=Transform(self.message)
            newmessage=messageinstance.random_letter()
            
        elif encoding==5:
            messageinstance=Transform(self.message)
            newmessage=messageinstance.random_shuffle()
            
        else:
            print "Encoding index out of bounds; select a number from 0-5"
            print "0=no encoding; message appears as-is 1= standard5-digit grouping, no spaces: 2=Transform()-encoding:"
            print "3=randomised word-order: 4=randomised character-order: 5=randomised character and word order"
            return
        finalmessage=""
        for i in range(0,len(newmessage)):
            
            if newmessage[i] ==" ":
                finalmessage+=" space ... "
            elif newmessage[i] in ["a","A"]:
                finalmessage+=" ay... "
            else:
                finalmessage+=newmessage[i].lower()+" ... "
        print finalmessage
    
        
            
        
        

##- - - -
    ## Initialises the GUI

root=Tk()
root.title("Encoder/Decoder APP")
root.geometry("405x420")

Application(root)   

root.mainloop()
